package com.qpf.mycms.api.handler;

import com.qpf.mycms.api.enums.HttpStatusEnum;
import com.qpf.mycms.api.exception.ServiceException;
import com.qpf.mycms.api.pojo.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(AccessDeniedException.class)
    public ResponseResult<?> handleAccessDeniedException(AccessDeniedException ex, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址[{}]'{}', 权限校验失败: {}", request.getMethod(), requestURI, ex.getMessage());
        return ResponseResult.fail(HttpStatusEnum.FORBIDDEN.getValue(), HttpStatusEnum.FORBIDDEN.getDesc());
    }
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ResponseResult<?> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException ex, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址[{}]'{}', 不支持'{}'请求", request.getMethod(), requestURI, ex.getMethod());
        return ResponseResult.fail(ex.getMessage());
    }
    @ExceptionHandler(ServiceException.class)
    public ResponseResult<?> handleServiceException(ServiceException ex, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        Integer code = ex.getCode();
        log.error("请求地址[{}]'{}', 异常: {}", request.getMethod(), requestURI, ex.getMessage());
        return ObjectUtils.isEmpty(code) ? ResponseResult.fail(ex.getMessage()) : ResponseResult.fail(code, ex.getMessage());
    }
    @ExceptionHandler(RuntimeException.class)
    public ResponseResult<?> handleORuntimeException(RuntimeException ex, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址[{}]'{}', 发生未知异常: {}", request.getMethod(), requestURI, ex.getMessage());
        return ResponseResult.fail(ex.getMessage());
    }
    @ExceptionHandler(BindException.class)
    public ResponseResult<?> handleBindException(BindException ex, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址[{}]'{}', 发生验证异常: {}", request.getMethod(), requestURI, ex.getMessage());
        return ResponseResult.fail(ex.getAllErrors().get(0).getDefaultMessage());
    }
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseResult<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址[{}]'{}', 发生参数验证异常: {}", request.getMethod(), requestURI, ex.getMessage());
        return ResponseResult.fail(Objects.requireNonNull(ex.getFieldError()).getDefaultMessage());
    }

}
